package com.tbit.uqbike.client.handler.borrowbikehandler;

import com.alibaba.fastjson.JSON;
import com.tbit.common.utils.TraceUtil;
import com.tbit.uqbike.center.pojo.MachineStatus;
import com.tbit.uqbike.client.common.ResultMsg;
import com.tbit.uqbike.client.constant.*;
import com.tbit.uqbike.client.dao.core.BorrowCheckConfigLogDao;
import com.tbit.uqbike.client.pojo.Machine;
import com.tbit.uqbike.client.pojo.Point;
import com.tbit.uqbike.client.pojo.borrowbike.BorrowCheckConfigLog;
import com.tbit.uqbike.client.pojo.newEntity.AccountConfigExt;
import com.tbit.uqbike.client.service.*;
import com.tbit.uqbike.client.util.GeoUtil;
import com.tbit.uqbike.client.vo.borrow.BorrowBikeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author lh2
 * @ClassName: AreaCheckHandler
 * @Description: 区域位置校验处理器（电子围栏，禁停区，站点等）
 * @date 2023-07-27 02:53:47
 */
@Slf4j
@Component
public class AreaCheckHandler extends AbstractCheckHandler {
    @Autowired
    private MachineStatusService machineStatusService;
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private GeoService geoService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private ForbiddenService forbiddenService;
    @Autowired
    private BorrowCheckConfigLogDao borrowCheckConfigLogMapper;

    @Override
    public ResultMsg handle(BorrowBikeVO vo, String serialNO) {
        log.info("【区域位置校验处理器】校验开始...");
        // 降级：如果配置了降级，则跳过此处理器，执行下一个处理器
        if (super.getConfig().getDown() == 1) {
            log.info("【区域位置校验处理器】被降级，已自动跳过！");
            return super.next(vo, serialNO);
        }

        Machine machine = vo.getMachine();
        // 判断车辆是否在电子围栏内
        MachineStatus machineStatus = machineStatusService.getByMachineNO(machine.getMachineNO(),
                MapConstant.MAP_GOOGLE);
        if (MachineStateConstant.MACHINE_TYPE_ELECT_BIKE.equals(machine.getMachineType())) {
            if (machineStatus != null && machineStatus.getLon() != null && machineStatus.getLat() != null) {
                if (machineStatus.getLon() == null || machineStatus.getLat() == null) {
                    return ResultMsg.fail(-3029, "故障车辆，车辆还没有上线", TraceUtil.getTraceIdByLocal());
                }
                Boolean isInArea = geoService.checkInGeo(machine.getAccountId(),
                        new Point(machineStatus.getLon(), machineStatus.getLat()));
                if (!isInArea) {
                    return ResultMsg.fail(-3047, "运营区域外禁止借车",TraceUtil.getTraceIdByLocal());
                }
                Boolean result = forbiddenService.checkInForbidden(machine.getUserCode(),
                        new Point(machineStatus.getLon(), machineStatus.getLat()));
                if (result) {
                    return ResultMsg.fail(-4007, "车辆在禁行区内,请更换车辆",TraceUtil.getTraceIdByLocal());
                }
                Point point = new Point(machineStatus.getLon(), machineStatus.getLat());
                AccountConfigExt ext = cacheService.getAccountConfigExtByKey(machine.getAccountId(),
                        AccountConfigExtConstant.ACCOUNTCONFIG_MACHINE_BORROW_RANGE);
                if (ext != null) {
                    Point point1 = new Point(vo.getLon(), vo.getLat());
                    point1 = calibrateService.calibrate(point1, vo.getMapType(), SysConstant.ORIGINAL);
                    Double distance = GeoUtil.getPointDistance(point1, point);
                    Integer value = Integer.valueOf(ext.getParamValue());
                    log.info("借车距离===" + distance + ",设置范围=" + value);
                    if (distance > value && value > 0) {
                        return ResultMsg.fail(-20023, "位置距离车辆过远，请更换车辆",TraceUtil.getTraceIdByLocal());
                    }
                }
                /** 缓存借车位置 */
                redisService.add(RedisConstant.MACHINE_BORROW_LOCAL + machine.getMachineNO(), JSON.toJSONString(point),
                        60);
            } else {
                return ResultMsg.fail(-3029, "故障车辆，车辆还没有投放",TraceUtil.getTraceIdByLocal());
            }
        }
        // 单车围栏逻辑判断
        if (machine.getMachineType().equals(MachineStateConstant.MACHINE_TYPE_BIKE)) {
            Point point = new Point(vo.getLon(), vo.getLat());
            point = calibrateService.calibrate(point, vo.getMapType(), SysConstant.ORIGINAL);
            Boolean isInArea = geoService.checkInGeo(machine.getAccountId(), point);
            if (!isInArea) {
                return ResultMsg.fail(-3047, "运营区域外禁止借车",TraceUtil.getTraceIdByLocal());
            }
        }

        log.info("【区域位置校验处理器】校验通过！");
        BorrowCheckConfigLog bccLog = borrowCheckConfigLogMapper.findByNameAndSerialNO(
                this.getConfig().getHandlerName(), serialNO);
        if (bccLog != null) {
            bccLog.setExecuteResult(1);
            borrowCheckConfigLogMapper.updateByPrimaryKeySelective(bccLog);
        }

        // 执行下一个处理器
        return super.next(vo, serialNO);
    }
}
